<?php
/**
 * Model
 *
 * PHP version 7
 *
 * @category  Model
 * @package   App\Models
 * @author    Guojing Liu <liugj@boqii.com>
 * @copyright 2016-2019 guangcheng Co. All Rights Reserved.
 * @license   http://opensource.org/licenses/gpl-2.0.php GNU General Public License
 * @version   GIT:<git_id>
 * @link      http://shop.openapi.boqii.com
 */

namespace App\Models;

use Illuminate\Database\Eloquent\Model as  BaseModel;
use Illuminate\Support\Collection;
use Cache;

class Model extends BaseModel
{
    /**
     * Timestamps
     *
     * @public boolean
     * @access public
     */
    public $timestamps = false;
    /**
     * Guarded
     *
     * @protected array
     * @access    protected
     */
    protected $guarded =[];

    /**
     * 保存store
     *
     * @param Illuminate\Support\Collection $input 输入参数
     * @param int                           $id    ID
     *
     * @access public
     *
     * @return int
     */
    public function store(Collection $input, int $id = 0) : int
    {
        if ($id > 0) {
            $this->findOrFail($id)->update($input->toArray());
            Cache :: forget(sprintf('%s_%d', get_class($this), $id));
        } else {
            $id = self :: create($input->toArray())->{$this->primaryKey};
        }

        Cache::tags($this->table)->flush();
        return $id;
    }

    /**
     * 详情展示show
     *
     * @param Illuminate\Support\Collection $input 输入参数
     * @param int                           $id    Id
     *
     * @access public
     *
     * @return mixed
     */
    public function show(Collection $input, int $id)
    {
        $useCache = $input->get('use_cache', true);
        if ($useCache) {
            $value = Cache :: remember(
                sprintf('%s_%d', get_class($this), $id),
                config('cache.duration.default'),
                function () use ($id) {
                        return $this->findOrFail($id)->toArray();
                }
            );
            return  $input->get('select') && $input->get('select') !='*' ?
                array_intersect_key(
                    is_object($value) ? $value->toArray(): $value,
                    array_flip(explode(',', $input['select']))
                ) : $value;
        } else {
            return  self :: select(explode(',', $input->get('select', '*')))
             ->findOrFail($id)->toArray();
        }
    }

    /**
     * 删除deleteById
     *
     * @param int $id ID
     *
     * @access public
     *
     * @return int
     */
    public function deleteById(int $id) : int
    {
        return  $this->destroy($id);
    }

    /**
     * BuildOrderSort
     *
     * @param string $strOrderSort 待处理排序字符串
     *
     * @access protected
     *
     * @return array
     */
    protected function buildOrderSort($strOrderSort) : array
    {
        $orderSorts = [];
        foreach (explode(',', $strOrderSort) as $orderSort) {
            if (substr_compare($orderSort, '_asc', -4, 4) ==0) {
                $orderSorts [] = sprintf(' %s ASC ', substr($orderSort, 0, -4));
            } elseif (substr_compare($orderSort, '_desc', -5, 5) ==0) {
                $orderSorts [] = sprintf(' %s DESC ', substr($orderSort, 0, -5));
            } else {
                $orderSorts [] = sprintf(' %s ASC ', $orderSort);
            }
        }

        return $orderSorts;
    }
    /**
     * BuildResultItem
     *
     * @param array $items 处理前item
     *
     * @access public
     *
     * @return array
     */
    protected function buildResultItem(array $items) : array
    {
        $newItems = [];
        foreach ($items as $key => $value) {
            if (strpos($key, '___') !== false) {
                list($table, $field) =  explode('___', $key);
                $newItems[$table][$field] = $value;
            } else {
                $newItems[$key] = $value;
            }
        }
        return [$newItems];
    }
    /**
     * buildSelectFields2Collection
     *
     * @param string $select
     *
     * @access protected
     *
     * @return Illuminate\Support\Collection
     */
    protected function buildSelectFields2Collection(string $select): Collection
    {
        $selectFields = collect([]);

        if (preg_match_all('#([0-9a-z_]+(\[[0-9a-z_,\*]+\])?),?#is', $select, $matches)) {
            foreach ($matches[1] as $str) {
                if (preg_match_all('#([0-9a-z_]+)\[([0-9a-z_,\*]+)\]#', $str, $matchesFields)) {
                    foreach (explode(',', $matchesFields[2][0]) as $field) {
                        if ($field = trim($field)) {
                            if ($selectFields->has($matchesFields[1][0])) {
                                $selectFields[$matchesFields[1][0]][$field] = $field;
                            } else {
                                $selectFields[$matchesFields[1][0]] = collect([$field=>$field]);
                            }
                        }
                    }
                } else {
                    $selectFields[$str] = $str;
                }
            }
        } else {
            $selectFields = collect(['*'=>'*']);
        }
        return  $selectFields;
    }
    /**
     * BuildSelectFields
     *
     * @param mixed $select 处理select
     *
     * @access public
     *
     * @return string
     */
    protected function buildSelectFields(string $select): string
    {
        $selectFields = [];

        if (preg_match_all('#([0-9a-z_]+(\[[0-9a-z_,\*]+\])?),?#is', $select, $matches)) {
            foreach ($matches[1] as $str) {
                if (preg_match_all('#([0-9a-z_]+)\[([0-9a-z_,\*]+)\]#', $str, $matchesFields)) {
                    foreach (explode(',', $matchesFields[2][0]) as $field) {
                        if (($field = trim($field)) !='*') {
                            $selectFields [] = sprintf(
                                '%s.%s AS  %s___%s',
                                $matchesFields[1][0],
                                $field,
                                $matchesFields[1][0],
                                $field
                            );
                        } else {
                            $selectFields [] = sprintf('%s.*', $matchesFields[1][0]);
                        }
                    }
                } else {
                    $selectFields[] = $str;
                }
            }
        } else {
            $selectFields = ['*'];
        }

        return  implode(',', $selectFields);
    }


    /**
     * 获取当前时间戳
     *
     * @return int
     * @author wuliang
     */
    public function freshTimestamp()
    {
        return time();
    }

    /**
     * 避免转换时间戳为时间字符串
     *
     * @param \DateTime|int $value
     *
     * @return \DateTime|int
     * @author wuliang
     */
    public function fromDateTime($value)
    {
        return $value;
    }
}
